package sql.dml.selecao;

import sql.ddl.TokensSQL;
import sql.dml.selecao.coluna.Oque;
import sql.dml.selecao.filtro.FiltroSQl;
import sql.dml.selecao.tabela.Onde;

public class Select implements TokensSQL {
	private FiltroSQl[] filtros = null;

	private Oque colunaOrdenar = null;

	private String outrasConfiguracoes = null;

	private Oque[] colunas = null;

	private Onde[] tabelas;

	private String maximoLinhasSelecionar = null;

	Select() {
	}

	public String codigoSQL() {
		return SELECT + SPACE + colunas() + SPACE + FROM + SPACE + tabelas()
				+ montaFiltro() + montaOrdenacao() + maximoLinhasSelecionar()
				+ montaConfiguracao();
	}

	private String maximoLinhasSelecionar() {
		return maximoLinhasSelecionar != null ? SPACE + LIMMIT + SPACE
				+ maximoLinhasSelecionar : NONVALUE;
	}

	private String colunas() {
		return colunas != null && colunas.length > 0 ? concatena(colunas) : "*";
	}

	private String concatena(Oque... colunas) {
		String s = colunas[0].codigoSQL();
		for (int i = 1; i < colunas.length; i++)
			s += VIRGUL + colunas[i].codigoSQL();
		return s;
	}

	private String tabelas() {
		String tabela = tabelas[0].codigoSQL();
		for (int i = 1; i < tabelas.length; i++)
			tabela += VIRGUL + tabelas[i].codigoSQL();
		return tabela;
	}

	private String montaOrdenacao() {
		return colunaOrdenar == null ? NONVALUE : SPACE + ORDER + SPACE + BY
				+ BEGINPARENTES + colunaOrdenar.getAlias() + ENDPARENTES;
	}

	private String montaConfiguracao() {
		return outrasConfiguracoes == null ? NONVALUE : SPACE
				+ outrasConfiguracoes;
	}

	private String montaFiltro() {
		return filtros == null || filtros.length < 1 ? NONVALUE : SPACE + WHERE
				+ SPACE + filtros();
	}

	private String filtros() {
		String s = filtros[0].codigoSQL();
		for (int i = 1; i < filtros.length; i++)
			s += SPACE+filtros[i].operadorCondicionalComOutrosFiltros() + SPACE
					+ filtros[i].codigoSQL();
		return s;
	}

	protected void setColunaOrdenar(Oque colunaOrdenar) {
		this.colunaOrdenar = colunaOrdenar;
	}

	protected void setColunas(Oque[] colunas) {
		this.colunas = colunas;
	}

	protected void setFiltros(FiltroSQl... filtros) {
		this.filtros = filtros;
	}

	protected void setMaximoLinhasSelecionar(String maximoLinhasSelecionar) {
		this.maximoLinhasSelecionar = maximoLinhasSelecionar;
	}

	public void setOutrasConfiguracoes(String outrasConfiguracoes) {
		this.outrasConfiguracoes = outrasConfiguracoes;
	}

	protected void setTabelas(Onde[] tabelas) {
		this.tabelas = tabelas;
	}
}
